#pragma once

#include <cv.h>
#include <highgui.h>
#include <opencv2/nonfree/nonfree.hpp>

#pragma comment(lib, "opencv_core243.lib")
#pragma comment(lib, "opencv_flann243.lib")
#pragma comment(lib, "opencv_highgui243.lib")
#pragma comment(lib, "opencv_legacy243.lib")
#pragma comment(lib, "opencv_imgproc243.lib")
#pragma comment(lib, "opencv_calib3d243.lib")
#pragma comment(lib, "opencv_nonfree243.lib")

namespace gtl
{

namespace opencv
{

struct ipl
{
	static IplImage* trans(HBITMAP hBmp, int nChannel = 1, int code = CV_BGRA2GRAY)
	{   
		BITMAP bmp;
		GetObject(hBmp, sizeof(BITMAP), &bmp);

		// get channels which equal 1 2 3 or 4 
		// bmBitsPixel:
		// Specifies the number of bits
		// required to indicate the color of a pixel.
		int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel / 8 ;

		// get depth color bitmap or grayscale
		int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;

		// create header image
		IplImage* img = cvCreateImage(cvSize(bmp.bmWidth, bmp.bmHeight), depth, nChannels);

		// allocat memory for the pBuffer
		BYTE *pBuffer = new BYTE[bmp.bmHeight * bmp.bmWidth * nChannels];

		// copies the bitmap bits of a specified device-dependent bitmap into a buffer
		GetBitmapBits(hBmp, bmp.bmHeight * bmp.bmWidth * nChannels, pBuffer);

		// copy data to the imagedata
		memcpy(img->imageData, pBuffer, bmp.bmHeight * bmp.bmWidth * nChannels);
		delete pBuffer;

		// create the image
		IplImage *dst = cvCreateImage(cvGetSize(img), img->depth, nChannel);
		// convert color
		cvCvtColor(img, dst, code);
		cvReleaseImage(&img);
		return dst;   
	}  
};

} // end of namespace cv

} // end of namespace gtl